package orm

import (
	"github.com/redis/go-redis/v9"
	"gorm.io/gorm"
	"hertz_demo/orm/cache"
	"hertz_demo/orm/db"
	"hertz_demo/orm/models"
)

func CreateUser(username string, password string) (int64, error) {
	newUser := db.User{
		Name:          username,
		Password:      password,
		FollowCount:   0,
		FollowerCount: 0,
	}
	err := db.DB.Transaction(func(tx *gorm.DB) error {
		var nameCnt int64 = 0
		if err := tx.Table("users").Where("name = ?", username).Count(&nameCnt).Error; err != nil {
			return err
		}
		if nameCnt != 0 {
			return gorm.ErrInvalidData
		}
		if err := tx.Create(&newUser).Error; err != nil {
			return gorm.ErrInvalidData
		}
		return nil
	})
	if err == nil {
		token := GenerateToken(newUser.Name)
		SetToken(int64(newUser.ID), token)
	}
	return newUser.ID, err
}

func GetUserById(userId int64) (models.User, error) {
	user, err := cache.GetUserById(userId)
	if err == redis.Nil {
		dbUser := new(db.User)
		db.DB.Model(&db.User{}).Find(dbUser, userId)
		err = cache.SetUser(dbUser)
		if err != nil {
			panic(err)
		}
		if dbUser.ID != 0 {
			user.ID = int64(dbUser.ID)
			user.Name = dbUser.Name
			user.FollowCount = dbUser.FollowCount
			user.FollowerCount = dbUser.FollowerCount
			user.IsFollow = false
		}
	} else if err != nil {
		panic(err)
	}
	return user, err
}

func GetUserByName(username string) (models.User, error) {
	user, err := cache.GetUserByName(username)
	if err == redis.Nil {
		dbUser := new(db.User)
		db.DB.Model(&db.User{}).Find(dbUser, "name = ?", username)
		err = cache.SetUser(dbUser)
		if err != nil {
			panic(err)
		}
		if dbUser.ID != 0 {
			user.ID = int64(dbUser.ID)
			user.Name = dbUser.Name
			user.FollowCount = dbUser.FollowCount
			user.FollowerCount = dbUser.FollowerCount
			user.IsFollow = false
		}
	} else if err != nil {
		panic(err)
	}
	return user, err
}

func LoginUser(username string, password string) (userId int64, token string, err error) {
	dbUser := new(db.User)
	db.DB.Model(&db.User{}).Find(dbUser, "name = ?", username)
	if dbUser.Password != password {
		err = gorm.ErrInvalidValue
	} else {
		token = GenerateToken(username)
		SetToken(dbUser.ID, token)
		userId = dbUser.ID
		err = nil
	}
	return
}
